package com.kust.smarhome.background.controller;


import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.kust.smarhome.background.common.dto.UserInfoDto;
import com.kust.smarhome.background.common.lang.Const;
import com.kust.smarhome.background.common.lang.Result;
import com.kust.smarhome.background.common.vo.PasswordVo;
import com.kust.smarhome.background.common.vo.UserVo;
import com.kust.smarhome.background.model.User;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.security.Principal;
import java.time.LocalDateTime;
import java.util.Objects;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author iAuzre
 * @since 2021-07-31
 */
@RestController
@RequestMapping("/user")
public class UserController extends BaseController {


    @Resource
    private BCryptPasswordEncoder passwordEncoder;

    @PostMapping("/userInfo")
    public Result userInfo(Principal principal) {

        User user = getUser(principal.getName());

        UserInfoDto userInfoDto = new UserInfoDto();
        userInfoDto.setId(user.getId())
                .setUsername(user.getUsername())
                .setLogourl(user.getPortrait());

        return Result.succ(userInfoDto);
    }

    @GetMapping("/list")
    public Result list(String username) {

        Page<User> pageData = userService.page(getPage(), new QueryWrapper<User>()
                .like(StrUtil.isNotBlank(username), "username", username));

        return Result.succ(pageData);
    }

    @PostMapping("/resetPwd/{id}")
    public Result resetPwt(@PathVariable Integer id, Principal principal) {

        User user = getUser(principal.getName());

        if (user.getPower() != 1)
            return Result.fail(401, "权限不足", null);

        User resetUser = userService.getById(id);
        if (resetUser.getPower() == 1)
            return Result.fail("不能对管理员进行操作");

        String password = passwordEncoder.encode(Const.DEFULT_PASSWORD);
        resetUser.setPassword(password);

        if (!userService.updateById(resetUser)) {
            return Result.fail("发生了不可描述的错误");
        }

        return Result.succ(null);


    }

    @PostMapping("/delete")
    @Transactional
    public Result delete(@RequestBody Integer[] ids, Principal principal) {
        User user = getUser(principal.getName());

        if (user.getPower() != 1)
            return Result.fail(401, "权限不足", null);

        for (int id : ids) {
            userService.removeById(id);
        }

        return Result.succ(null);
    }

    @PostMapping("/ban/{id}")
    public Result ban(@PathVariable Integer id, Principal principal) {

        User user = getUser(principal.getName());

        if (user.getPower() != 1) {
            return Result.fail(401, "权限不足", null);
        }

        User banUser = userService.getById(id)
                .setLocked(1);

        if (!userService.updateById(banUser) || banUser.getPower() == 1) {
            return Result.fail("操作失败!");
        }

        return Result.succ(null);
    }

    @PostMapping("/banOff/{id}")
    public Result banOff(@PathVariable Integer id, Principal principal) {

        User user = getUser(principal.getName());

        if (user.getPower() != 1) {
            return Result.fail(401, "权限不足", null);
        }

        User banUser = userService.getById(id)
                .setLocked(0);

        if (!userService.updateById(banUser) || banUser.getPower() == 1) {
            return Result.fail("操作失败!");
        }

        return Result.succ(null);
    }

    @PostMapping("/setUser")
    public Result setUser(@RequestBody @Validated UserVo userVo, BindingResult result, Principal principal) {

        if (result.hasErrors())
            return Result.fail(result.getFieldError().getDefaultMessage());

        User user = userService.getByUsername(userVo.getUsername());

        if (user != null)
            return Result.fail("用户名已存在");

        String password = passwordEncoder.encode(userVo.getPassword());

        user = new User()
                .setUsername(userVo.getUsername())
                .setPassword(password)
                .setNickname(userVo.getNickname())
                .setLocked(userVo.getState())
                .setState(Const.STATUS_ON)
                .setEnabled(1)
                .setPortrait(Const.DEFULT_AVATAR)
                .setPower(Const.POWER_OFF)
                .setCreated(LocalDateTime.now());

        if (!userService.save(user))
            return Result.fail("添加失败");

        return Result.succ(null);
    }

    @PostMapping("/updatePass")
    public Result updatePass(@RequestBody @Validated PasswordVo passwordVo, BindingResult result, Principal principal) {

        if (result.hasErrors())
            return Result.fail(result.getFieldError().getDefaultMessage());

//        QueryWrapper<User> query = new QueryWrapper<>();
//        query.select("username", principal.getName());
//        User u = userService.getOne(query);
        User user = userService.getByUsername(principal.getName());

        if (user == null || Objects.equals(user, new User())) {
            return Result.fail("系统错误");
        }

        boolean matches = passwordEncoder.matches(passwordVo.getCurrentPass(), user.getPassword());
        if (!matches)
            return Result.fail("密码不正确!");

        if (!passwordVo.getPassword().equals(passwordVo.getCheckPass()))
            return Result.fail("密码不一致!");

        String password = passwordEncoder.encode(passwordVo.getCheckPass());
        user.setPassword(password);
        if (!userService.updateById(user))
            return Result.fail("操作失败");

        return Result.succ(null);
    }

    private User getUser(String username) {
        return userService.getByUsername(username);
    }

}
